/**
 * 用户行为埋点工具类
 * 支持自动埋点和手动埋点功能
 */

class UserTracking {
  constructor() {
    this.isEnabled = process.env.NODE_ENV === 'production' || process.env.REACT_APP_TRACKING_ENABLED === 'true';
    this.batchSize = 50;
    this.batchTimeout = 3000; // 3秒
    this.eventQueue = [];
    this.sessionId = this.generateSessionId();
    this.userId = null;
    this.batchTimer = null;
    
    // 初始化设备信息
    this.deviceInfo = this.getDeviceInfo();
    
    if (this.isEnabled) {
      this.init();
    }
  }
  
  /**
   * 初始化埋点系统
   */
  init() {
    console.log('用户行为埋点系统已启动');
    
    // 自动埋点：页面访问
    this.trackPageView();
    
    // 自动埋点：页面卸载
    window.addEventListener('beforeunload', () => {
      this.flushEvents(true); // 同步发送
    });
    
    // 自动埋点：页面可见性变化
    document.addEventListener('visibilitychange', () => {
      if (document.visibilityState === 'hidden') {
        this.flushEvents(true);
      }
    });
    
    // 自动埋点：点击事件
    document.addEventListener('click', (event) => {
      this.trackClick(event);
    });
    
    // 自动埋点：表单提交
    document.addEventListener('submit', (event) => {
      this.trackFormSubmit(event);
    });
    
    // 自动埋点：滚动事件（节流）
    let scrollTimer = null;
    document.addEventListener('scroll', () => {
      if (scrollTimer) clearTimeout(scrollTimer);
      scrollTimer = setTimeout(() => {
        this.trackScroll();
      }, 1000);
    });
    
    // 启动批量发送定时器
    this.startBatchTimer();
  }
  
  /**
   * 设置用户ID
   */
  setUserId(userId) {
    this.userId = userId;
  }
  
  /**
   * 生成会话ID
   */
  generateSessionId() {
    return 'session_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
  }
  
  /**
   * 获取设备信息
   */
  getDeviceInfo() {
    const ua = navigator.userAgent;
    const screen = window.screen;
    
    return {
      userAgent: ua,
      deviceInfo: this.getDeviceType(),
      browserInfo: this.getBrowserInfo(ua),
      osInfo: this.getOSInfo(ua),
      screenResolution: `${screen.width}x${screen.height}`,
      language: navigator.language,
      timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
    };
  }
  
  /**
   * 获取设备类型
   */
  getDeviceType() {
    const ua = navigator.userAgent;
    if (/tablet|ipad|playbook|silk/i.test(ua)) {
      return 'Tablet';
    }
    if (/mobile|iphone|ipod|android|blackberry|opera|mini|windows\sce|palm|smartphone|iemobile/i.test(ua)) {
      return 'Mobile';
    }
    return 'Desktop';
  }
  
  /**
   * 获取浏览器信息
   */
  getBrowserInfo(ua) {
    let browser = 'Unknown';
    if (ua.indexOf('Chrome') > -1) {
      browser = 'Chrome';
    } else if (ua.indexOf('Firefox') > -1) {
      browser = 'Firefox';
    } else if (ua.indexOf('Safari') > -1) {
      browser = 'Safari';
    } else if (ua.indexOf('Edge') > -1) {
      browser = 'Edge';
    } else if (ua.indexOf('Opera') > -1) {
      browser = 'Opera';
    }
    
    // 提取版本号
    const version = ua.match(new RegExp(browser + '/([0-9.]+)'));
    return browser + (version ? ' ' + version[1] : '');
  }
  
  /**
   * 获取操作系统信息
   */
  getOSInfo(ua) {
    let os = 'Unknown';
    if (ua.indexOf('Windows NT 10.0') > -1) os = 'Windows 10';
    else if (ua.indexOf('Windows NT 6.3') > -1) os = 'Windows 8.1';
    else if (ua.indexOf('Windows NT 6.2') > -1) os = 'Windows 8';
    else if (ua.indexOf('Windows NT 6.1') > -1) os = 'Windows 7';
    else if (ua.indexOf('Windows NT 6.0') > -1) os = 'Windows Vista';
    else if (ua.indexOf('Windows NT 5.1') > -1) os = 'Windows XP';
    else if (ua.indexOf('Windows NT 5.0') > -1) os = 'Windows 2000';
    else if (ua.indexOf('Mac') > -1) os = 'Mac/iOS';
    else if (ua.indexOf('X11') > -1) os = 'UNIX';
    else if (ua.indexOf('Linux') > -1) os = 'Linux';
    return os;
  }
  
  /**
   * 创建基础事件数据
   */
  createBaseEvent(eventType, eventData = {}) {
    return {
      timestamp: new Date().toISOString(),
      userId: this.userId,
      sessionId: this.sessionId,
      eventType,
      pageUrl: window.location.href,
      pageTitle: document.title,
      referrer: document.referrer,
      ...this.deviceInfo,
      eventData: JSON.stringify(eventData)
    };
  }
  
  /**
   * 添加事件到队列
   */
  addEvent(event) {
    if (!this.isEnabled) return;
    
    this.eventQueue.push(event);
    
    // 如果队列达到批量大小，立即发送
    if (this.eventQueue.length >= this.batchSize) {
      this.flushEvents();
    }
  }
  
  /**
   * 启动批量发送定时器
   */
  startBatchTimer() {
    if (this.batchTimer) {
      clearInterval(this.batchTimer);
    }
    
    this.batchTimer = setInterval(() => {
      if (this.eventQueue.length > 0) {
        this.flushEvents();
      }
    }, this.batchTimeout);
  }
  
  /**
   * 发送事件队列
   */
  async flushEvents(sync = false) {
    if (this.eventQueue.length === 0) return;
    
    const events = [...this.eventQueue];
    this.eventQueue = [];
    
    try {
      const url = '/api/admin/logs/user-tracking';
      const options = {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ events })
      };
      
      if (sync) {
        // 同步发送（页面卸载时）
        if (navigator.sendBeacon) {
          navigator.sendBeacon(url, JSON.stringify({ events }));
        } else {
          // 降级到同步 fetch
          await fetch(url, { ...options, keepalive: true });
        }
      } else {
        // 异步发送
        await fetch(url, options);
      }
      
      console.log(`成功发送 ${events.length} 个用户行为事件`);
    } catch (error) {
      console.error('发送用户行为事件失败:', error);
      // 发送失败时，将事件重新加入队列
      this.eventQueue.unshift(...events);
    }
  }
  
  /**
   * 页面访问埋点
   */
  trackPageView() {
    const event = this.createBaseEvent('page_view', {
      loadTime: performance.now(),
      documentReady: document.readyState
    });
    this.addEvent(event);
  }
  
  /**
   * 点击事件埋点
   */
  trackClick(clickEvent) {
    const target = clickEvent.target;
    const tagName = target.tagName.toLowerCase();
    
    // 只跟踪特定元素的点击
    if (['button', 'a', 'input'].includes(tagName) || target.getAttribute('data-track')) {
      const event = this.createBaseEvent('button_click', {
        elementType: tagName,
        elementId: target.id,
        elementClass: target.className,
        elementText: target.textContent || target.value || target.alt,
        elementHref: target.href,
        position: {
          x: clickEvent.clientX,
          y: clickEvent.clientY
        }
      });
      this.addEvent(event);
    }
  }
  
  /**
   * 表单提交埋点
   */
  trackFormSubmit(submitEvent) {
    const form = submitEvent.target;
    const formData = new FormData(form);
    const fields = {};
    
    // 收集表单字段信息（不包含敏感数据）
    for (let [key, value] of formData.entries()) {
      if (!this.isSensitiveField(key)) {
        fields[key] = typeof value === 'string' ? value.length : 'file';
      }
    }
    
    const event = this.createBaseEvent('form_submit', {
      formId: form.id,
      formClass: form.className,
      formAction: form.action,
      formMethod: form.method,
      fieldCount: Object.keys(fields).length,
      fields
    });
    this.addEvent(event);
  }
  
  /**
   * 滚动事件埋点
   */
  trackScroll() {
    const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
    const scrollHeight = document.documentElement.scrollHeight - window.innerHeight;
    const scrollPercent = Math.round((scrollTop / scrollHeight) * 100);
    
    const event = this.createBaseEvent('scroll', {
      scrollTop,
      scrollPercent,
      viewportHeight: window.innerHeight,
      documentHeight: document.documentElement.scrollHeight
    });
    this.addEvent(event);
  }
  
  /**
   * 自定义事件埋点
   */
  track(eventType, eventData = {}) {
    const event = this.createBaseEvent(eventType, eventData);
    this.addEvent(event);
  }
  
  /**
   * 检查是否为敏感字段
   */
  isSensitiveField(fieldName) {
    const sensitiveFields = ['password', 'pwd', 'token', 'secret', 'key', 'credit', 'card', 'ssn', 'phone', 'email'];
    return sensitiveFields.some(field => fieldName.toLowerCase().includes(field));
  }
  
  /**
   * 销毁埋点系统
   */
  destroy() {
    if (this.batchTimer) {
      clearInterval(this.batchTimer);
      this.batchTimer = null;
    }
    
    // 发送剩余事件
    this.flushEvents(true);
  }
}

// 创建全局实例
const userTracking = new UserTracking();

// 导出实例和类
export default userTracking;
export { UserTracking };

// 全局方法
window.track = (eventType, eventData) => userTracking.track(eventType, eventData);
window.setUserId = (userId) => userTracking.setUserId(userId);